package com.jacklin.product.service.impl;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jacklin.product.domain.Product;
import com.jacklin.product.mapper.ProductMapper;
import com.jacklin.product.service.ProductService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

/**
 * @describe: 商品库存服务实现类
 * @author: jacklin
 * @date: 2022-03-28 22:24
 */
@Service
public class ProductServiceImpl extends ServiceImpl<ProductMapper, Product> implements ProductService {

    @Autowired
    private RedisTemplate redisTemplate;


    /**
     * 执行扣库存的脚本
     */
    public static final String STOCK_LUA;

    static {
        StringBuilder sb = new StringBuilder();
        sb.append("if (redis.call('exists', KEYS[1]) == 1) then");
        sb.append("    local stock = tonumber(redis.call('get', KEYS[1]));");
        sb.append("    local num = tonumber(ARGV[1]);");
        sb.append("    if (stock == -1) then");
        sb.append("        return -1;");
        sb.append("    end;");
        sb.append("    if (stock >= num) then");
        sb.append("        return redis.call('incrby', KEYS[1], 0 - num);");
        sb.append("    end;");
        sb.append("    return -2;");
        sb.append("end;");
        sb.append("return -3;");
        STOCK_LUA = sb.toString();
    }


    /**
     * 根据商品id获取库存
     *
     * @param id 商品id
     * @return -1不限库存；大于等于0：剩余库存
     *
     * @author: jacklin
     * @date: 2022/8/4 9:17
     **/
    @Override
    public int getStock(Integer id) {
        Integer stock = (Integer) redisTemplate.opsForValue().get(id);
        return stock == null ? -1 : stock;
    }

    @Override
    public Boolean reduceStock(Integer id, Integer amount) {
        return update(Wrappers.<Product>lambdaUpdate().eq(Product::getId, id).ge(Product::getStock, amount).setSql("stock = stock-" + amount));
    }

}
